package com.zzyl.service.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.Constants;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.properties.WeChatProperties;
import com.zzyl.service.WeChatService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class WeChatServiceImpl implements WeChatService {

    private final WeChatProperties weChatProperties;

    private static final String LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

    private static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";

    private static final String GET_PHONE_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";

    /**
     * 获取openId
     * @param code
     * @return
     */
    @Override
    public String getOpenId(String code) {

        //构建请求参数
        Map<String, Object> params = new HashMap<>();

        params.put(Constants.APPID, weChatProperties.getAppid());
        params.put(Constants.SECRET, weChatProperties.getSecret());
        params.put(Constants.JS_CODE, code);
        params.put(Constants.GRANT_TYPE, "authorization_code");

        //发请求
        HttpResponse result = HttpUtil.createRequest(Method.GET, LOGIN_URL)
                .form(params)
                .execute();
        if (result.getStatus() != 200){
            throw new BaseException(BasicEnum.GET_OPENID_ERROR);
        }
        String resultJson = result.body();
        JSONObject json = JSONUtil.parseObj(resultJson);
        Integer errcode = json.get("errcode", Integer.class);
        if (null == errcode || 0 == errcode.intValue()){
            return json.get("openid", String.class);
        }
        throw new BaseException(BasicEnum.GET_OPENID_ERROR);
    }

    /**
     * 获取手机号
     * @param phoneCode
     * @return
     */
    @Override
    public String getPhoneNumber(String phoneCode) {

        String accessToken = getAccessToken();
        //构建请求参数
        Map<String, Object> phoneNumberParams = new HashMap<>();
        phoneNumberParams.put("code", phoneCode);
        //发请求
        HttpResponse result = HttpUtil.createRequest(Method.POST, GET_PHONE_URL + accessToken)
                .body(JSONUtil.toJsonStr(phoneNumberParams))
                .execute();
        if (result.getStatus() != 200){
            throw new BaseException(BasicEnum.GET_PHONE_ERROR);
        }
        String phoneJson = result.body();
        JSONObject phoneJsonObj = JSONUtil.parseObj(phoneJson);
        Integer phoneErrcode = phoneJsonObj.get("errcode", Integer.class);
        if (null == phoneErrcode || 0 == phoneErrcode.intValue()){
            return phoneJsonObj.getByPath("phone_info.purePhoneNumber", String.class);
        }
        throw new BaseException(BasicEnum.GET_PHONE_ERROR);
    }

    /**
     * 获取accessToken
     * @return
     */
    private String getAccessToken(){
        //先获取accessToken
        //构建请求参数
        Map<String, Object> accessTokenParams = new HashMap<>();

        accessTokenParams.put(Constants.APPID, weChatProperties.getAppid());
        accessTokenParams.put(Constants.SECRET, weChatProperties.getSecret());
        accessTokenParams.put(Constants.GRANT_TYPE, "client_credential");

        //发请求
        HttpResponse res = HttpUtil.createRequest(Method.GET, GET_ACCESS_TOKEN_URL)
                .form(accessTokenParams)
                .execute();
        if (res.getStatus() != 200){
            throw new BaseException(BasicEnum.GET_TOKEN_ERROR);
        }
        //解析
        String resultJson = res.body();
        JSONObject json = JSONUtil.parseObj(resultJson);
        Integer errcode = json.get("errcode", Integer.class);
        if (null == errcode || 0 == errcode.intValue()){
            //得到accessToken
            return json.get("access_token", String.class);
        }
        throw new BaseException(BasicEnum.GET_TOKEN_ERROR);
    }
}

